package cn.com.aiouyi.page;

import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import java.io.Serializable;

/**
 * 筛选
 * 
 * @author hanson
 */
@Getter
@Setter
public class Criterion implements Serializable {

	private static final long serialVersionUID = -8712382358441065075L;

	/**
	 * 运算符
	 */
	public enum Operator {

		/** 等于 */
		eq,

		/** 不等于 */
		ne,

		/** 大于 */
		gt,

		/** 小于 */
		lt,

		/** 大于等于 */
		ge,

		/** 小于等于 */
		le,

		/** 相似 */
		like,

		/** 包含 */
		in,

		/** 为Null */
		isNull,

		/** 不为Null */
		isNotNull,
		
		/** 在范围之间 */
		between
	}

	/** 默认是否忽略大小写 */
	private static final boolean DEFAULT_IGNORE_CASE = false;

	/** 属性 */
	private String property;

	/** 运算符 */
	private Criterion.Operator operator;

	/** 值 */
	private Object value;

	/** 第二个值 */
	private Object secondValue;

	/** 无值条件 */
	private boolean isNoValue;

	/** 单个值条件 */
    private boolean isSingleValue;

    /** Between条件 */
    private boolean isBetweenValue;

    /** 多个值（列表）条件 */
    private boolean isListValue;

    /** 类型处理器 */
    private String typeHandler;

	/** 是否忽略大小写 */
	private Boolean ignoreCase = DEFAULT_IGNORE_CASE;

	/**
	 * 构造方法
	 */
	public Criterion() {
	}

	/**
	 * 构造方法
	 * @param property 属性
	 * @param operator 运算符
	 * @param value 值
	 */
	public Criterion(String property, Criterion.Operator operator, Object value) {
		this.property = property;
		this.operator = operator;
		this.value = value;
		if(operator == Operator.in){
			this.isListValue = true;
		}else{
			this.isSingleValue = true;
		}
	}

	/**
	 * 构造方法
	 * @param property  属性
	 * @param operator 运算符
	 * @param value 值
	 * @param ignoreCase 忽略大小写
	 */
	public Criterion(String property, Criterion.Operator operator, Object value, boolean ignoreCase) {
		this.property = property;
		this.operator = operator;
		this.value = value;
		this.ignoreCase = ignoreCase;
		if(operator == Operator.in){
			this.isListValue = true;
		}else{
			this.isSingleValue = true;
		}
	}

	/**
	 *
	 * @param property
	 * @param operator
	 * @param value
	 * @param secondValue
	 */
	public Criterion(String property, Criterion.Operator operator, Object value, Object secondValue) {
		this.property = property;
		this.operator = operator;
		this.value = value;
		this.secondValue = secondValue;
		this.isBetweenValue = true;
	}

	/**
	 * 返回等于筛选
	 * @param property 属性
	 * @param value 值
	 * @return 等于筛选
	 */
	public static Criterion eq(String property, Object value) {
		return new Criterion(property, Criterion.Operator.eq, value);
	}

	/**
	 * 返回等于筛选
	 * @param property 属性
	 * @param value 值
	 * @param ignoreCase 忽略大小写
	 * @return 等于筛选
	 */
	public static Criterion eq(String property, Object value, boolean ignoreCase) {
		return new Criterion(property, Criterion.Operator.eq, value, ignoreCase);
	}

	/**
	 * 返回不等于筛选
	 * @param property 属性
	 * @param value 值
	 * @return 不等于筛选
	 */
	public static Criterion ne(String property, Object value) {
		return new Criterion(property, Criterion.Operator.ne, value);
	}

	/**
	 * 返回不等于筛选
	 * @param property 属性
	 * @param value 值
	 * @param ignoreCase  忽略大小写
	 * @return 不等于筛选
	 */
	public static Criterion ne(String property, Object value, boolean ignoreCase) {
		return new Criterion(property, Criterion.Operator.ne, value, ignoreCase);
	}

	/**
	 * 返回大于筛选
	 * @param property  属性
	 * @param value 值
	 * @return 大于筛选
	 */
	public static Criterion gt(String property, Object value) {
		return new Criterion(property, Criterion.Operator.gt, value);
	}

	/**
	 * 返回小于筛选
	 * @param property 属性
	 * @param value 值
	 * @return 小于筛选
	 */
	public static Criterion lt(String property, Object value) {
		return new Criterion(property, Criterion.Operator.lt, value);
	}

	/**
	 * 返回大于等于筛选
	 * @param property 属性
	 * @param value 值
	 * @return 大于等于筛选
	 */
	public static Criterion ge(String property, Object value) {
		return new Criterion(property, Criterion.Operator.ge, value);
	}

	/**
	 * 返回小于等于筛选
	 * @param property 属性
	 * @param value  值
	 * @return 小于等于筛选
	 */
	public static Criterion le(String property, Object value) {
		return new Criterion(property, Criterion.Operator.le, value);
	}

	/**
	 * 返回相似筛选
	 * @param property 属性
	 * @param value 值
	 * @return 相似筛选
	 */
	public static Criterion like(String property, Object value) {
		return new Criterion(property, Criterion.Operator.like, value);
	}

	/**
	 * 返回包含筛选
	 * @param property 属性
	 * @param value 值
	 * @return 包含筛选
	 */
	public static Criterion in(String property, Object value) {
		return new Criterion(property, Criterion.Operator.in, value);
	}

	/**
	 * 返回为Null筛选
	 * @param property 属性
	 * @return 为Null筛选
	 */
	public static Criterion isNull(String property) {
		return new Criterion(property, Criterion.Operator.isNull, null);
	}

	/**
	 * 返回不为Null筛选
	 * @param property 属性
	 * @return 不为Null筛选
	 */
	public static Criterion isNotNull(String property) {
		return new Criterion(property, Criterion.Operator.isNotNull, null);
	}

	/**
	 * 返回不为Null筛选
	 * @param property 属性
	 * @return 不为Null筛选
	 */
	public static Criterion between(String property, Object value, Object secondValue) {
		return new Criterion(property, Criterion.Operator.between, value, secondValue);
	}


	/**
	 * 重写equals方法
	 * 
	 * @param obj
	 *            对象
	 * @return 是否相等
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		if (this == obj) {
			return true;
		}
		Criterion other = (Criterion) obj;
		return new EqualsBuilder().append(getProperty(), other.getProperty()).append(getOperator(), other.getOperator()).append(getValue(), other.getValue()).isEquals();
	}

	/**
	 * 重写hashCode方法
	 * 
	 * @return HashCode
	 */
	@Override
	public int hashCode() {
		return new HashCodeBuilder(17, 37).append(getProperty()).append(getOperator()).append(getValue()).toHashCode();
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "property="+this.property+"==>value="+this.value;
	}
}